﻿//using OpenTK.Audio.OpenAL;
//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
//using ttbit.core;
//using ttbit.IAL;

//namespace ttbit.Windows
//{
//    public class AudioSource : IDisposable
//    {
//        int audiosrc;
//        int buf1;
//        int buf2;
//        bool buf1free;
//        bool buf2free;
//        short[] buf;
//        public AudioSource()
//        {
//            audiosrc = AL.GenSource();
//            buf1 = AL.GenBuffer();
//            buf2 = AL.GenBuffer();
//            buf1free = true;
//            buf2free = true;
//            buf = new short[7552];//学anroid算出来的数字，这个不到0.1秒，44100 0.1s sample =8820
//            Volume = 1.0f;
//            Active = true;
//        }
//        public float Volume
//        {
//            get;
//            private set;
//        }
//        public bool Active;
//        public void SetVolume(float v)
//        {
//            this.Volume = v;
//            AL.Source(audiosrc, ALSourcef.Gain, v);
//        }
//        //改成双缓冲 阻塞式
//        public unsafe bool Write(short* data, int sizeinbyte, int freq = 44100, bool stereo = true)
//        {
//            int seek = 0;
//            while (Active && seek < sizeinbyte / 2)
//            {
//                fixed (short* pbuf = buf)
//                {
//                    //copy buf
//                    int bufsize = sizeinbyte / 2 - seek;
//                    if (bufsize > buf.Length) bufsize = buf.Length;
//                    for (var i = 0; i < bufsize; i++)
//                    {
//                        pbuf[i] = data[seek + i];
//                    }

//                    //write can write
//                    while (!buf1free && !buf2free)
//                    {
//                        AL.GetSource(audiosrc, ALGetSourcei.BuffersProcessed, out int v);
//                        if (v > 0)
//                        {
//                            int[] _bufs = AL.SourceUnqueueBuffers(audiosrc, v);
//                            foreach (var j in _bufs)
//                            {
//                                if (j == buf1)
//                                    buf1free = true;
//                                else if (j == buf2)
//                                    buf2free = true;
//                            }
//                        }
//                        if (!buf1free && !buf2free)
//                            System.Threading.Thread.Sleep(10);
//                    }
//                    int usebufid = buf1free ? buf1 : buf2;

//                    AL.BufferData(usebufid, stereo ? ALFormat.Stereo16 : ALFormat.Mono16, pbuf, bufsize * 2, freq);
//                    AL.SourceQueueBuffer(audiosrc, usebufid);


//                    var state = AL.GetSourceState(audiosrc);
//                    if (state == ALSourceState.Stopped || state == ALSourceState.Initial)
//                    {
//                        AL.SourcePlay(audiosrc);
//                    }
//                    seek += bufsize;

//                    if (buf1free)
//                        buf1free = false;
//                    else
//                        buf2free = false;
//                }
//            }
//            return Active;
//        }

//        public void Stop()
//        {
//            AL.SourceStop(audiosrc);
//            AL.GetSource(audiosrc, ALGetSourcei.BuffersQueued, out int v);
//            AL.SourceUnqueueBuffers(audiosrc, v);
//        }

//        public void Dispose()
//        {
//            Stop();
//            AL.DeleteSource(audiosrc);
//            AL.DeleteBuffer(buf1);
//            AL.DeleteBuffer(buf2);
//        }
//    }
//    internal class ALWin : IAL.IAudio
//    {
//        public int MaxTrackCount => 16;
//        AudioSource[] audios;
//        public ALWin()
//        {
//            audios = new AudioSource[MaxTrackCount];
//            var device = OpenTK.Audio.OpenAL.ALC.OpenDevice(null);
//            var context = ALC.CreateContext(device, (int[]?)null);
//            ALC.MakeContextCurrent(context);
//        }

//        public void SetTrackVolume(int channel, float volume)
//        {
//            audios[channel].SetVolume(volume);
//        }

//        public float GetTrackVolume(int channel)
//        {
//            return audios[channel].Volume;
//        }
//        public bool IsTrackOpen(int channel)
//        {
//            if (audios[channel] == null)
//                return false;
//            return audios[channel].Active;
//        }
//        public void OpenTrack(int channel)
//        {
//            if (audios[channel] == null)
//            {
//                audios[channel] = new AudioSource();
//            }
//            audios[channel].Active = true;
//        }

//        public void CloseTrack(int channel)
//        {
//            if (audios[channel] != null)
//            {
//                audios[channel].Stop();
//                audios[channel].Active = false;
//            }
//        }

//        public void WriteTrack(int channel, short[] samples, int offset = 0, int length = -1)
//        {
//            if (length < 0)
//                length = samples.Length;
//            unsafe
//            {
//                fixed (short* ptr = samples)
//                {
//                    short* buffer = ptr + offset;
//                    audios[channel].Write(buffer, length * 2);
//                }
//            }
//            System.Threading.Thread.Sleep(0);
//        }

//        public void WriteTrackBytes(int channel, byte[] samples, int offset = 0, int lengthinbyte = -1)
//        {
//            if (lengthinbyte < 0)
//                lengthinbyte = samples.Length;
//            unsafe
//            {
//                fixed (byte* ptr = samples)
//                {
//                    short* buffer = (short*)(ptr + offset);
//                    audios[channel].Write(buffer, lengthinbyte);
//                }
//            }
//            System.Threading.Thread.Sleep(0);
//        }

//    }
//}
